package TCP

import (
	"SupperControl/protocol"
	"context"
	"fmt"
	"io"
	"net"
	"sync"
)

// 这个结构会有三个协程用，一个负责收数据，一个负责发数据，一个负责逻辑处理,
//逻辑处理有可能还会与其它连接关联处理，怎么同步还没想好

type Protocol_TCP struct {
	protocol.ProtocolBase
	waitClose sync.WaitGroup
	context   context.Context
}

func (this *Protocol_TCP) SendData(avData []uint8) {
	var lvSendData = protocol.Metadata{}
	lvSendData.Head.DataLen = uint32(len(avData))
	lvSendData.Data = avData
	this.SendQ <- lvSendData
}

func (this *Protocol_TCP) handleExtendHead(avData []uint8) {

}

func (this *Protocol_TCP) WriteALL(w io.Writer, data []byte) bool {
	println("protocol_TCP WriteALL!")
	totalWritten := 0
	for totalWritten < len(data) {
		n, err := w.Write(data[totalWritten:])
		if err != nil {
			return false
		}
		totalWritten += n
	}
	return true
}

func (this *Protocol_TCP) ReadAll(r io.Reader, buf []byte) (n int, err error) {
	println("protocol_TCP ReadAll!")
	return io.ReadFull(r, buf)
}

func handleRecv(avClient *Protocol_TCP) {
	defer func() {
		println("handleRecv Ended")
		close(avClient.RecvQ)
		avClient.waitClose.Done()
	}()
tagBreakAll:
	for {
		select {
		case <-avClient.context.Done():
			break tagBreakAll
		case <-avClient.CloseChan:
			break tagBreakAll
		default:
			if avClient.ProcessRecvData(avClient) {
				var lvRecvData protocol.Metadata
				lvRecvData.Head = avClient.ConnData.RecvHead
				lvRecvData.ExtendData = avClient.ConnData.RecvExtendData
				lvRecvData.Data = avClient.ConnData.RecvData
				avClient.RecvQ <- lvRecvData
			} else {
				break tagBreakAll
			}
		}
	}
}

func handleSend(avClient *Protocol_TCP) {
	defer func() {
		println("handleSend Ended")
		close(avClient.SendQ)
		avClient.waitClose.Done()
	}()
tagBreakAll:
	for {
		select {
		case lvSendData, lvOK := <-avClient.SendQ:
			if !lvOK {
				break
			}
			avClient.ConnData.SendData = lvSendData.Data
			avClient.ConnData.SendHeadData = lvSendData.Head
			avClient.ConnData.SendExtendData = lvSendData.ExtendData
			if !avClient.ProcessSendData(&avClient.ProtocolBase) {
				break
			}
		case <-avClient.CloseChan:
			break tagBreakAll
		}
	}
}

func handleLogic(avClient *Protocol_TCP) {
	defer func() {
		close(avClient.CloseChan)
	}()

	println("连接上来了:", avClient.Conn.RemoteAddr().String())
	lvContext, lvCancel := context.WithCancel(context.Background())

	defer lvCancel()
	avClient.context = lvContext

	go handleRecv(avClient)
	go handleSend(avClient)

tagBreakAll:
	for {
		select {
		case lvRecvData, lvOK := <-avClient.RecvQ:
			if !lvOK {
				break tagBreakAll
			}
			println(lvRecvData.Data)
		}
	}

	lvRemoateAddr := avClient.Conn.RemoteAddr().String()
	avClient.Exit()
	avClient.Conn.Close()
	avClient.waitClose.Wait()
	protocol.ConnLists.Delete(avClient.ConnIndex)
	println("断开连接了:", lvRemoateAddr)
}

func StartTCPSvr(avAddr string) {
	lvListener, lvErr := net.Listen("tcp", avAddr)
	if lvErr != nil {
		fmt.Println("Error listening:", lvErr)
		return
	}
	defer lvListener.Close()

	fmt.Println("TCP Server is listening on", avAddr)

	var lvConnIndex uint64 = 0
	for {
		lvConn, lvErr := lvListener.Accept()
		if lvErr != nil {
			fmt.Println("Error accepting connection:", lvErr)
			continue
		}
		lvConnIndex += 1
		var lvClient Protocol_TCP
		lvClient.InitClient(lvConn, lvConnIndex)
		lvClient.waitClose.Add(2)
		lvClient.OnExtendHead = lvClient.handleExtendHead

		protocol.ConnLists.Store(lvConnIndex, protocol.TConnInfo{Protocol: &lvClient.ProtocolBase})
		// 启动一个 goroutine 处理连接
		go handleLogic(&lvClient)
	}
}
